//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

import React, { useEffect, useState } from 'react';
import type { UserServerInfo, SshServerInfo, SqlServerInfo, MongoServerInfo, RedisServerInfo, GrpcServerInfo } from "@/api/user_server";
import { add_server, update_server } from "@/api/user_server";
import { Button, Card, Checkbox, Form, Input, InputNumber, List, message, Modal, Radio, Select, Space } from 'antd';
import { APP_TYPE_GRPC, APP_TYPE_MONGO, APP_TYPE_MYSQL, APP_TYPE_POSTGRES, APP_TYPE_REDIS, APP_TYPE_SSH, type APP_TYPE } from '@/api/appstore';
import { uniqId } from '@/utils/utils';
import { FolderOpenOutlined, MinusCircleOutlined, PlusCircleOutlined } from '@ant-design/icons';
import { basename, resolve } from '@tauri-apps/api/path';
import { homeDir } from '@tauri-apps/api/path';
import { list_ssh_key_name } from '@/api/local_repo';
import { open as dialog_open } from '@tauri-apps/api/dialog';
import { useTranslation } from "react-i18next";

interface AddrWithId {
    id: string;
    addr: string;
}

interface PathWithId {
    id: string;
    path: string;
}

interface RedisServerExtInfo {
    addrs: AddrWithId[];
    dbId: number;
    username: string;
    password: string;
}

interface MongoServerExtInfo {
    addrs: AddrWithId[];
    username: string;
    password: string;
    authSource: string;
    authMechanism: string;
    replicaSet: string;
    defaultDb: string;
};

interface GrpcServerExtInfo {
    addr: string;
    rootPath: string;
    importPathList: PathWithId[];
    secure: boolean;
}

export interface EditServModalProps {
    projectId?: string;
    serverInfo?: UserServerInfo;
    appType?: APP_TYPE;
    onCancel: () => void;
    onOk: () => void;
}

const EditServModal = (props: EditServModalProps) => {
    const { t } = useTranslation();

    const [name, setName] = useState(props.serverInfo?.name ?? "");
    const [servType, setServType] = useState<APP_TYPE>(props.serverInfo?.server_type ?? (props.appType ?? APP_TYPE_SSH));

    const [sshInfo, setSshInfo] = useState<SshServerInfo>({
        addr: "",
        username: "",
        usePrivKey: false,
        password: "",
        privKeyPath: "",
        privKeyPassword: "",
    });

    const [mysqlInfo, setMySqlInfo] = useState<SqlServerInfo>({
        driver: "mysql",
        addr: "",
        username: "",
        password: "",
    });

    const [postgresInfo, setPostgresInfo] = useState<SqlServerInfo>({
        driver: "postgres",
        addr: "",
        username: "",
        password: "",
    });

    const [mongoInfo, setMongoInfo] = useState<MongoServerExtInfo>({
        addrs: [
            {
                id: uniqId(),
                addr: "",
            },
        ],
        username: "",
        password: "",
        authSource: "admin",
        authMechanism: "SCRAM-SHA-256",
        replicaSet: "",
        defaultDb: "",
    });

    const [redisInfo, setRedisInfo] = useState<RedisServerExtInfo>({
        addrs: [
            {
                id: uniqId(),
                addr: "",
            },
        ],
        dbId: 0,
        username: "",
        password: "",
    });

    const [grpcInfo, setGrpcInfo] = useState<GrpcServerExtInfo>({
        addr: "",
        rootPath: "",
        importPathList: [],
        secure: false,
    });

    const [sshKeyList, setSshKeyList] = useState([] as string[]);
    const [curSshKey, setCurSshKey] = useState("");

    const loadSshKeyList = async () => {
        const res = await list_ssh_key_name();
        setSshKeyList(res);
    };

    const checkValid = () => {
        if (name == "") {
            return false;
        }
        if (servType == APP_TYPE_SSH) {
            if (sshInfo.addr == "" || sshInfo.username == "") {
                return false;
            }
            if (sshInfo.usePrivKey) {
                if (sshInfo.privKeyPath == "") {
                    return false;
                }
            } else {
                if (sshInfo.password == "") {
                    return false;
                }
            }
            return true;
        } else if (servType == APP_TYPE_MYSQL) {
            if (mysqlInfo.addr == "" || mysqlInfo.username == "") {
                return false;
            }
            return true;
        } else if (servType == APP_TYPE_POSTGRES) {
            if (postgresInfo.addr == "" || postgresInfo.username == "") {
                return false;
            }
            return true;
        } else if (servType == APP_TYPE_MONGO) {
            if (mongoInfo.addrs.length == 0) {
                return false;
            }
            for (const addr of mongoInfo.addrs) {
                if (addr.addr == "") {
                    return false;
                }
            }
            if (mongoInfo.username == "" && mongoInfo.password != "") {
                return false;
            } else if (mongoInfo.username != "" && mongoInfo.password == "") {
                return false;
            }
            return true;
        } else if (servType == APP_TYPE_REDIS) {
            if (redisInfo.addrs.length == 0) {
                return false;
            }
            for (const addr of redisInfo.addrs) {
                if (addr.addr == "") {
                    return false;
                }
            }
            return true;
        } else if (servType == APP_TYPE_GRPC) {
            if (grpcInfo.rootPath == "") {
                return false;
            }
            if (grpcInfo.addr.includes(":") == false) {
                return false;
            }
            return true;
        }
        return false;
    };

    const checkMongoUserAndPasswd = () => {
        if (mongoInfo.username == "" && mongoInfo.password != "") {
            return false;
        } else if (mongoInfo.username != "" && mongoInfo.password == "") {
            return false;
        }
        return true;
    };


    const genUserServerInfo = () => {
        const info: UserServerInfo = {
            id: props.serverInfo?.id ?? uniqId(),
            name: name,
            server_type: servType,
            server_info: "",
            project_id: props.projectId ?? (props.serverInfo?.project_id),
        };
        if (servType == APP_TYPE_SSH) {
            info.server_info = JSON.stringify(sshInfo);
        } else if (servType == APP_TYPE_MYSQL) {
            info.server_info = JSON.stringify(mysqlInfo);
        } else if (servType == APP_TYPE_POSTGRES) {
            info.server_info = JSON.stringify(postgresInfo);
        } else if (servType == APP_TYPE_MONGO) {
            const tmpInfo: MongoServerInfo = {
                ...mongoInfo,
                addrs: mongoInfo.addrs.map(addr => addr.addr),
            };
            info.server_info = JSON.stringify(tmpInfo);
        } else if (servType == APP_TYPE_REDIS) {
            const tmpInfo: RedisServerInfo = {
                ...redisInfo,
                addrs: redisInfo.addrs.map(addr => addr.addr),
            };
            info.server_info = JSON.stringify(tmpInfo);
        } else if (servType == APP_TYPE_GRPC) {
            const tmpInfo: GrpcServerInfo = {
                ...grpcInfo,
                importPathList: grpcInfo.importPathList.map(path => path.path),
            }
            info.server_info = JSON.stringify(tmpInfo);
        }
        return info;
    };

    const addServer = async () => {
        const info = genUserServerInfo();
        await add_server(info);
        props.onOk();
        message.info(t("text.addSuccess"));
    };

    const updateServer = async () => {
        const info = genUserServerInfo();
        await update_server(info);
        props.onOk();
        message.info(t("text.updateSuccess"));
    };

    const adjustSshKeyPath = async (tmpSshKey: string) => {
        if (tmpSshKey == "") {
            setSshInfo({
                ...sshInfo,
                privKeyPath: "",
            });
            return;
        }
        const homePath = await homeDir();
        const path = await resolve(homePath, ".ssh", tmpSshKey);
        setSshInfo({
            ...sshInfo,
            privKeyPath: path,
        });
    };

    const choiceRootPath = async () => {
        const selected = await dialog_open({
            title: "选择Grpc定义路径",
            directory: true,
        });
        if (selected == null) {
            return;
        }
        if (Array.isArray(selected)) {
            return;
        }
        setGrpcInfo({
            ...grpcInfo,
            rootPath: selected,
        });
    };

    const choiceImportPath = async (pathId: string) => {
        const selected = await dialog_open({
            title: "选择导入路径",
            directory: true,
        });
        if (selected == null) {
            return;
        }
        if (Array.isArray(selected)) {
            return;
        }
        const tmpList = grpcInfo.importPathList.slice();
        const index = tmpList.findIndex(item => item.id == pathId);
        if (index != -1) {
            tmpList[index].path = selected;
            setGrpcInfo({
                ...grpcInfo,
                importPathList: tmpList,
            });
        }
    };

    useEffect(() => {
        if (props.serverInfo == undefined) {
            return;
        }
        if (props.serverInfo.server_type == APP_TYPE_SSH) {
            const info = JSON.parse(props.serverInfo.server_info) as SshServerInfo;
            if (info.usePrivKey) {
                if (info.privKeyPath != "") {
                    basename(info.privKeyPath).then(tmpName => {
                        setCurSshKey(tmpName);
                        setSshInfo(info);
                    });
                } else {
                    setSshInfo(info);
                }
            } else {
                setSshInfo(info);
            }
        } else if (props.serverInfo.server_type == APP_TYPE_MYSQL) {
            const info = JSON.parse(props.serverInfo.server_info) as SqlServerInfo;
            setMySqlInfo(info);
        } else if (props.serverInfo.server_type == APP_TYPE_POSTGRES) {
            const info = JSON.parse(props.serverInfo.server_info) as SqlServerInfo;
            setPostgresInfo(info);
        } else if (props.serverInfo.server_type == APP_TYPE_MONGO) {
            const info = JSON.parse(props.serverInfo.server_info) as MongoServerInfo;
            setMongoInfo({
                addrs: info.addrs.map(addr => ({
                    id: uniqId(),
                    addr: addr,
                })),
                username: info.username,
                password: info.password,
                authSource: info.authSource,
                authMechanism: info.authMechanism,
                replicaSet: info.replicaSet,
                defaultDb: info.defaultDb,
            });
        } else if (props.serverInfo.server_type == APP_TYPE_REDIS) {
            const info = JSON.parse(props.serverInfo.server_info) as RedisServerInfo;
            setRedisInfo({
                addrs: info.addrs.map(addr => ({
                    id: uniqId(),
                    addr: addr,
                })),
                dbId: info.dbId,
                username: info.username,
                password: info.password,
            });
        } else if (props.serverInfo.server_type == APP_TYPE_GRPC) {
            const info = JSON.parse(props.serverInfo.server_info) as GrpcServerInfo;
            setGrpcInfo({
                addr: info.addr,
                rootPath: info.rootPath,
                importPathList: info.importPathList.map(path => ({
                    id: uniqId(),
                    path: path,
                })),
                secure: info.secure,
            });
        }
    }, [props.serverInfo]);


    useEffect(() => {
        if (servType == APP_TYPE_SSH) {
            loadSshKeyList();
        }
    }, [servType]);

    return (
        <Modal open title={`${props.serverInfo == undefined ? t("workbench.userServer.add") : t("workbench.userServer.update")}`} mask={false}
            okText={props.serverInfo == undefined ? t("text.add") : t("text.update")} okButtonProps={{ disabled: !checkValid() }}
            bodyStyle={{ maxHeight: "calc(100vh - 300px)", overflowY: "scroll" }}
            onCancel={e => {
                e.stopPropagation();
                e.preventDefault();
                props.onCancel();
            }}
            onOk={e => {
                e.stopPropagation();
                e.preventDefault();
                if (props.serverInfo == undefined) {
                    addServer();
                } else {
                    updateServer();
                }
            }}>
            <Form labelCol={{ span: 5 }}>
                <Form.Item label={t("text.tip")}>
                    {t("workbench.userServer.modalTip")}
                </Form.Item>
                <Form.Item label={t("text.name")}>
                    <Input value={name} onChange={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        setName(e.target.value.trim());
                    }} status={name == "" ? "error" : undefined} disabled={(props.serverInfo?.project_id ?? "") != ""} />
                </Form.Item>
                <Form.Item label={t("text.serviceType")}>
                    <Select value={servType} onChange={value => setServType(value)} disabled={props.serverInfo != undefined || props.appType != undefined}>
                        <Select.Option value={APP_TYPE_SSH}>SSH</Select.Option>
                        <Select.Option value={APP_TYPE_MYSQL}>MYSQL</Select.Option>
                        <Select.Option value={APP_TYPE_POSTGRES}>POSTGRES</Select.Option>
                        <Select.Option value={APP_TYPE_MONGO}>MONGO</Select.Option>
                        <Select.Option value={APP_TYPE_REDIS}>REDIS</Select.Option>
                        <Select.Option value={APP_TYPE_GRPC}>GRPC</Select.Option>
                    </Select>
                </Form.Item>

                {servType == APP_TYPE_SSH && (
                    <>
                        <Form.Item label={t("workbench.userServer.remoteAddr")}>
                            <Input value={sshInfo.addr} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setSshInfo({
                                    ...sshInfo,
                                    addr: e.target.value.trim(),
                                });
                            }} status={sshInfo.addr == "" ? "error" : undefined} disabled={(props.serverInfo?.project_id ?? "") != ""} />
                        </Form.Item>
                        <Form.Item label={t("text.username")}>
                            <Input value={sshInfo.username} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setSshInfo({
                                    ...sshInfo,
                                    username: e.target.value.trim(),
                                });
                            }} status={sshInfo.username == "" ? "error" : undefined} />
                        </Form.Item>
                        <Form.Item label={t("text.authMethod")}>
                            <Radio.Group value={sshInfo.usePrivKey} onChange={e => {
                                e.stopPropagation();
                                setSshInfo({
                                    ...sshInfo,
                                    usePrivKey: e.target.value,
                                });
                            }}>
                                <Radio value={false}>{t("text.authByPassword")}</Radio>
                                <Radio value={true}>{t("text.authByKey")}</Radio>
                            </Radio.Group>
                        </Form.Item>
                        {sshInfo.usePrivKey == false && (
                            <Form.Item label={t("text.password")}>
                                <Input.Password value={sshInfo.password} onChange={e => {
                                    e.stopPropagation();
                                    e.preventDefault();
                                    setSshInfo({
                                        ...sshInfo,
                                        password: e.target.value.trim(),
                                    });
                                }} status={sshInfo.password == "" ? "error" : undefined} />
                            </Form.Item>
                        )}
                        {sshInfo.usePrivKey && (
                            <>
                                <Form.Item label={t("text.keyName")}>
                                    <Select value={curSshKey} onChange={value => {
                                        setCurSshKey(value);
                                        adjustSshKeyPath(value);
                                    }}
                                        status={curSshKey == "" ? "error" : undefined}>
                                        {sshKeyList.map(item => (
                                            <Select.Option key={item} value={item}>{item}</Select.Option>
                                        ))}
                                    </Select>
                                </Form.Item>
                                <Form.Item label={t("text.keyPassword")}>
                                    <Input.Password value={sshInfo.privKeyPassword} onChange={e => {
                                        e.stopPropagation();
                                        e.preventDefault();
                                        setSshInfo({
                                            ...sshInfo,
                                            privKeyPassword: e.target.value.trim(),
                                        });
                                    }} />
                                </Form.Item>
                            </>
                        )}
                    </>
                )}

                {servType == APP_TYPE_MYSQL && (
                    <>
                        <Form.Item label={t("workbench.userServer.remoteAddr")}>
                            <Input value={mysqlInfo.addr} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setMySqlInfo({
                                    ...mysqlInfo,
                                    addr: e.target.value.trim(),
                                });
                            }} status={mysqlInfo.addr == "" ? "error" : undefined} disabled={(props.serverInfo?.project_id ?? "") != ""} />
                        </Form.Item>
                        <Form.Item label={t("text.username")}>
                            <Input value={mysqlInfo.username} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setMySqlInfo({
                                    ...mysqlInfo,
                                    username: e.target.value.trim(),
                                });
                            }} status={mysqlInfo.username == "" ? "error" : undefined} />
                        </Form.Item>
                        <Form.Item label={t("text.password")}>
                            <Input.Password value={mysqlInfo.password} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setMySqlInfo({
                                    ...mysqlInfo,
                                    password: e.target.value.trim(),
                                });
                            }} status={mysqlInfo.password == "" ? "error" : undefined} />
                        </Form.Item>
                    </>
                )}

                {servType == APP_TYPE_POSTGRES && (
                    <>
                        <Form.Item label={t("workbench.userServer.remoteAddr")}>
                            <Input value={postgresInfo.addr} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setPostgresInfo({
                                    ...postgresInfo,
                                    addr: e.target.value.trim(),
                                });
                            }} status={postgresInfo.addr == "" ? "error" : undefined} disabled={(props.serverInfo?.project_id ?? "") != ""} />
                        </Form.Item>
                        <Form.Item label={t("text.username")}>
                            <Input value={postgresInfo.username} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setPostgresInfo({
                                    ...postgresInfo,
                                    username: e.target.value.trim(),
                                });
                            }} status={postgresInfo.username == "" ? "error" : undefined} />
                        </Form.Item>
                        <Form.Item label={t("text.password")}>
                            <Input.Password value={postgresInfo.password} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setPostgresInfo({
                                    ...postgresInfo,
                                    password: e.target.value.trim(),
                                });
                            }} status={postgresInfo.password == "" ? "error" : undefined} />
                        </Form.Item>
                    </>
                )}

                {servType == APP_TYPE_MONGO && (
                    <>
                        <Form.Item label={t("workbench.userServer.remoteAddr")}>
                            <List rowKey="id" dataSource={mongoInfo.addrs} pagination={false}
                                renderItem={(addrItem, itemIndex) => (
                                    <List.Item extra={
                                        <Space size="small">
                                            <Button type="link" icon={<PlusCircleOutlined />} style={{ minWidth: 0, padding: "0px 0px" }}
                                                onClick={e => {
                                                    e.stopPropagation();
                                                    e.preventDefault();
                                                    const tmpList = mongoInfo.addrs.slice();
                                                    tmpList.splice(itemIndex + 1, 0, {
                                                        id: uniqId(),
                                                        addr: "",
                                                    });
                                                    setMongoInfo({
                                                        ...mongoInfo,
                                                        addrs: tmpList,
                                                    });
                                                }} disabled={(props.serverInfo?.project_id ?? "") != ""} />
                                            <Button type="link" icon={<MinusCircleOutlined />} disabled={mongoInfo.addrs.length <= 1 || (props.serverInfo?.project_id ?? "") != ""} style={{ minWidth: 0, padding: "0px 0px" }}
                                                onClick={e => {
                                                    e.stopPropagation();
                                                    e.preventDefault();
                                                    const tmpList = mongoInfo.addrs.filter(item => item.id != addrItem.id);
                                                    setMongoInfo({
                                                        ...mongoInfo,
                                                        addrs: tmpList,
                                                    });
                                                }} />
                                        </Space>
                                    }>
                                        <Input value={addrItem.addr} onChange={e => {
                                            e.stopPropagation();
                                            e.preventDefault();
                                            const tmpList = mongoInfo.addrs.slice();
                                            tmpList[itemIndex].addr = e.target.value.trim();
                                            setMongoInfo({
                                                ...mongoInfo,
                                                addrs: tmpList,
                                            });
                                        }} status={addrItem.addr == "" ? "error" : undefined} disabled={(props.serverInfo?.project_id ?? "") != ""} />
                                    </List.Item>
                                )} />
                        </Form.Item>
                        <Form.Item label={t("text.username")}>
                            <Input value={mongoInfo.username} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setMongoInfo({
                                    ...mongoInfo,
                                    username: e.target.value.trim(),
                                });
                            }} status={checkMongoUserAndPasswd() == false ? "error" : undefined} />
                        </Form.Item>
                        <Form.Item label={t("text.password")}>
                            <Input.Password value={mongoInfo.password} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setMongoInfo({
                                    ...mongoInfo,
                                    password: e.target.value.trim(),
                                });
                            }} status={checkMongoUserAndPasswd() == false ? "error" : undefined} />
                        </Form.Item>
                        <Form.Item label={t("workbench.userServer.authDb")}>
                            <Input value={mongoInfo.authSource} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setMongoInfo({
                                    ...mongoInfo,
                                    authSource: e.target.value.trim(),
                                });
                            }} />
                        </Form.Item>
                        <Form.Item label={t("text.authMethod")}>
                            <Select value={mongoInfo.authMechanism} onChange={value => setMongoInfo({
                                ...mongoInfo,
                                authMechanism: value,
                            })}>
                                <Select.Option value="SCRAM-SHA-1">SCRAM-SHA-1</Select.Option>
                                <Select.Option value="SCRAM-SHA-256">SCRAM-SHA-256</Select.Option>
                            </Select>
                        </Form.Item>
                        <Form.Item label={t("workbench.userServer.replicaSet")}>
                            <Input value={mongoInfo.replicaSet} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setMongoInfo({
                                    ...mongoInfo,
                                    replicaSet: e.target.value.trim(),
                                });
                            }} />
                        </Form.Item>
                        <Form.Item label={t("workbench.userServer.accessDb")}>
                            <Input value={mongoInfo.defaultDb} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setMongoInfo({
                                    ...mongoInfo,
                                    defaultDb: e.target.value.trim(),
                                });
                            }} />
                        </Form.Item>
                    </>
                )}

                {servType == APP_TYPE_REDIS && (
                    <>
                        <Form.Item label={t("workbench.userServer.remoteAddr")}>
                            <List rowKey="id" dataSource={redisInfo.addrs} pagination={false}
                                renderItem={(addrItem, itemIndex) => (
                                    <List.Item extra={
                                        <Space size="small">
                                            <Button type="link" icon={<PlusCircleOutlined />} style={{ minWidth: 0, padding: "0px 0px" }}
                                                onClick={e => {
                                                    e.stopPropagation();
                                                    e.preventDefault();
                                                    const tmpList = redisInfo.addrs.slice();
                                                    tmpList.splice(itemIndex + 1, 0, {
                                                        id: uniqId(),
                                                        addr: "",
                                                    });
                                                    setRedisInfo({
                                                        ...redisInfo,
                                                        addrs: tmpList,
                                                    });
                                                }} disabled={(props.serverInfo?.project_id ?? "") != ""} />
                                            <Button type="link" icon={<MinusCircleOutlined />} disabled={redisInfo.addrs.length <= 1 || (props.serverInfo?.project_id ?? "") != ""} style={{ minWidth: 0, padding: "0px 0px" }}
                                                onClick={e => {
                                                    e.stopPropagation();
                                                    e.preventDefault();
                                                    const tmpList = redisInfo.addrs.filter(item => item.id != addrItem.id);
                                                    setRedisInfo({
                                                        ...redisInfo,
                                                        addrs: tmpList,
                                                    });
                                                }} />
                                        </Space>
                                    }>
                                        <Input value={addrItem.addr} onChange={e => {
                                            e.stopPropagation();
                                            e.preventDefault();
                                            const tmpList = redisInfo.addrs.slice();
                                            tmpList[itemIndex].addr = e.target.value.trim();
                                            setRedisInfo({
                                                ...redisInfo,
                                                addrs: tmpList,
                                            });
                                        }} status={addrItem.addr == "" ? "error" : undefined} disabled={(props.serverInfo?.project_id ?? "") != ""} />
                                    </List.Item>
                                )} />
                        </Form.Item>
                        <Form.Item label={t("text.username")}>
                            <Input value={redisInfo.username} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setRedisInfo({
                                    ...redisInfo,
                                    username: e.target.value.trim(),
                                });
                            }} />
                        </Form.Item>
                        <Form.Item label={t("text.password")}>
                            <Input.Password value={redisInfo.password} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setRedisInfo({
                                    ...redisInfo,
                                    password: e.target.value.trim(),
                                });
                            }} />
                        </Form.Item>
                        <Form.Item label={t("workbench.userServer.defaultDb")}>
                            <InputNumber value={redisInfo.dbId} controls={false} precision={0} min={0} max={64}
                                style={{ width: "100%" }}
                                onChange={value => {
                                    if (value != null) {
                                        setRedisInfo({
                                            ...redisInfo,
                                            dbId: value,
                                        });
                                    }
                                }} />
                        </Form.Item>
                    </>
                )}
                {servType == APP_TYPE_GRPC && (
                    <>
                        <Form.Item label={t("workbench.userServer.remoteAddr")} help={t("workbench.userServer.remoteAddrTip")}>
                            <Input value={grpcInfo.addr} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setGrpcInfo({
                                    ...grpcInfo,
                                    addr: e.target.value.trim(),
                                });
                            }} status={grpcInfo.addr.includes(":") ? undefined : "error"} disabled={(props.serverInfo?.project_id ?? "") != ""} />
                        </Form.Item>
                        <Form.Item label={t("text.useTls")}>
                            <Checkbox checked={grpcInfo.secure} onChange={e => {
                                e.stopPropagation();
                                setGrpcInfo({
                                    ...grpcInfo,
                                    secure: e.target.checked,
                                });
                            }} />
                        </Form.Item>
                        <Form.Item label={t("workbench.userServer.protoPath")}>
                            <Input value={grpcInfo.rootPath} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                setGrpcInfo({
                                    ...grpcInfo,
                                    rootPath: e.target.value.trim(),
                                });
                            }} addonAfter={
                                <Button type="text" icon={<FolderOpenOutlined />} style={{ height: "20px", minWidth: 0, padding: "0px 0px" }}
                                    onClick={e => {
                                        e.stopPropagation();
                                        e.preventDefault();
                                        choiceRootPath();
                                    }} />
                            } />
                        </Form.Item>
                        <Form.Item label={t("workbench.userServer.importPath")} help={t("workbench.userServer.importPathTip")}>
                            <Card bordered={false} extra={
                                <Button type="primary" onClick={e => {
                                    e.stopPropagation();
                                    e.preventDefault();
                                    const tmpList = grpcInfo.importPathList.slice();
                                    tmpList.unshift({
                                        id: uniqId(),
                                        path: "",
                                    });
                                    setGrpcInfo({
                                        ...grpcInfo,
                                        importPathList: tmpList,
                                    });
                                }}>{t("workbench.userServer.addImportPath")}</Button>
                            }>
                                {grpcInfo.importPathList.length > 0 && (
                                    <List rowKey="id" dataSource={grpcInfo.importPathList} pagination={false} renderItem={pathItem => (
                                        <List.Item extra={
                                            <Button type="link" onClick={e => {
                                                e.stopPropagation();
                                                e.preventDefault();
                                                const tmpList = grpcInfo.importPathList.filter(item => item.id != pathItem.id);
                                                setGrpcInfo({
                                                    ...grpcInfo,
                                                    importPathList: tmpList,
                                                });
                                            }}>{t("text.remove")}</Button>
                                        }>
                                            <Input value={pathItem.path} onChange={e => {
                                                e.stopPropagation();
                                                e.preventDefault();
                                                const tmpList = grpcInfo.importPathList.slice();
                                                const index = tmpList.findIndex(item => item.id == pathItem.id);
                                                if (index != -1) {
                                                    tmpList[index].path = e.target.value.trim();
                                                    setGrpcInfo({
                                                        ...grpcInfo,
                                                        importPathList: tmpList,
                                                    });
                                                }
                                            }} addonAfter={
                                                <Button type="text" icon={<FolderOpenOutlined />} style={{ height: "20px", minWidth: 0, padding: "0px 0px" }}
                                                    onClick={e => {
                                                        e.stopPropagation();
                                                        e.preventDefault();
                                                        choiceImportPath(pathItem.id);
                                                    }} />
                                            } />
                                        </List.Item>
                                    )} />
                                )}
                            </Card>
                        </Form.Item>
                    </>
                )}
            </Form>
        </Modal>
    );
};

export default EditServModal;